﻿/**************************************************************
 *
 * 唯一标识：f7fcbf23-3679-4391-a32b-045713f2acf1
 * 命名空间：Sgr.EntityFrameworkCore
 * 创建时间：2024/6/18 20:07:05
 * 机器名称：DESKTOP-HJ4OAG9
 * 创建者：CocoYuan
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;

namespace Sgr.EntityFrameworkCore
{
    public class SgrReadOnlyDbContext : DbContext
    {
        private const string ReadOnlyErrorMessage = "This is a read-only context, write operations are not supported";

        private readonly IEnumerable<IEntityFrameworkTypeProvider> _configurations;

        public SgrReadOnlyDbContext(DbContextOptions<SgrReadOnlyDbContext> options,
            IEnumerable<IEntityFrameworkTypeProvider> configurations)
            : base(options)
        {
            _configurations = configurations ?? throw new ArgumentNullException(nameof(configurations));

            // 配置为无跟踪查询，提高查询性能
            ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

            // 禁用自动检测变更，进一步提高性能
            ChangeTracker.AutoDetectChangesEnabled = false;
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            foreach (var conf in _configurations)
            {
                conf.RegisterEntities(modelBuilder, this.GetDatabaseType());
            }

            // 为所有实体的 DateTime / DateTime? 属性应用 UTC 值转换器
            modelBuilder.ApplyUtcDateTimeConverters();
        }

        #region 写入操作重写

        /// <summary>
        /// 重写保存更改方法，阻止保存操作
        /// </summary>
        public override int SaveChanges(bool acceptAllChangesOnSuccess)
        {
            throw new InvalidOperationException(ReadOnlyErrorMessage);
        }

        /// <summary>
        /// 重写异步保存更改方法，阻止保存操作
        /// </summary>
        public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
            CancellationToken cancellationToken = default)
        {
            throw new InvalidOperationException(ReadOnlyErrorMessage);
        }

        /// <summary>
        /// 重写添加实体方法
        /// </summary>
        public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
        {
            throw new InvalidOperationException(ReadOnlyErrorMessage);
        }

        /// <summary>
        /// 重写更新实体方法
        /// </summary>
        public override EntityEntry<TEntity> Update<TEntity>(TEntity entity)
        {
            throw new InvalidOperationException(ReadOnlyErrorMessage);
        }

        /// <summary>
        /// 重写删除实体方法
        /// </summary>
        public override EntityEntry<TEntity> Remove<TEntity>(TEntity entity)
        {
            throw new InvalidOperationException(ReadOnlyErrorMessage);
        }

        #endregion 写入操作重写
    }
}